package org.openea.eap.module.obpm.service.custsql.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.sf.jsqlparser.JSQLParserException;
import org.openbpm.base.api.exception.BusinessMessage;
import org.openbpm.base.api.query.QueryFilter;
import org.openbpm.base.api.query.QueryOP;
import org.openbpm.base.api.response.impl.ResultMsg;
import org.openbpm.base.core.id.IdUtil;
import org.openbpm.base.core.model.BaseModel;
import org.openbpm.base.core.util.ExceptionUtil;
import org.openbpm.base.core.util.StringUtil;
import org.openbpm.base.db.model.query.DefaultQueryFilter;
import org.openbpm.base.manager.impl.BaseManager;
import org.openea.eap.module.obpm.dao.custsql.FormCustSqlDao;
import org.openea.eap.module.obpm.service.custsql.FormCustSqlFieldsManager;
import org.openea.eap.module.obpm.service.custsql.FormCustSqlManager;
import org.openea.eap.module.obpm.service.custsql.FormCustSqlRelationManager;
import org.openea.eap.module.obpm.model.custsql.FormCustSql;
import org.openea.eap.module.obpm.model.custsql.FormCustSqlFields;
import org.openea.eap.module.obpm.model.custsql.FormCustSqlRelation;
import org.openea.eap.module.obpm.util.custsql.JSONObjectUtil;
import org.openea.eap.module.obpm.util.custsql.JdbcTemplateUtil;
import org.openea.eap.module.obpm.util.custsql.SqlUtil;
import org.openea.eap.module.obpm.util.custsql.TableOperUtil;
import org.openea.eap.module.obpm.model.custsql.vo.SqlButtonVO;
import org.openea.eap.module.obpm.model.custsql.vo.SqlConditionVO;
import org.openea.eap.module.obpm.model.custsql.vo.SqlFieldsVO;
import org.openbpm.sys.api.freemark.IFreemarkerEngine;
import org.openbpm.sys.api.service.ISysDataSourceService;
import org.openbpm.sys.core.dao.SysTreeNodeDao;
import org.openbpm.sys.core.model.SysTreeNode;
import org.openbpm.sys.util.ContextUtil;
import org.openea.eap.module.obpm.util.form.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


@Primary
@Service("formCustSqlManager")
public class FormCustSqlManagerImpl
        extends BaseManager<String, FormCustSql>
        implements FormCustSqlManager {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    FormCustSqlDao formCustSqlDao;

    @Resource
    FormCustSqlFieldsManager formCustSqlFieldsManager;

    @Autowired
    IFreemarkerEngine freemarkerEngine;

    @Autowired
    ISysDataSourceService sysDataSourceService;

    @Autowired
    FormCustSqlRelationManager formCustSqlRelationMananger;

    @Resource
    SysTreeNodeDao sysTreeNodeDao;


    public ResultMsg<String> save(FormCustSql formCustSql) {
        String id = formCustSql.getId();

        ResultMsg<String> checkParams = checkParams(formCustSql, id);
        if (!checkParams.getIsOk().booleanValue()) {
            return checkParams;
        }

        // json字段
        formCustSql.setButtons(JSONObjectUtil.toListString(formCustSql.getButtons(), SqlButtonVO.class));

        formCustSql.setConditions(JSONObjectUtil.toListString(formCustSql.getConditions(), SqlConditionVO.class));

        if (formCustSql.getCustForm() != null) {
            formCustSql.setFormKey(formCustSql.getCustForm().getFormKey());
        }


        if (StringUtil.isEmpty(id)) {
            // 新增

            id = IdUtil.getSuid();
            formCustSql.setCreateBy(ContextUtil.getCurrentUserId());
            formCustSql.setCreator(ContextUtil.getCurrentUserName());
            formCustSql.setCreateTime(new Date());
            formCustSql.setId(id);
            formCustSql.setVersion(1);
            create(formCustSql);


            saveSqlFields(formCustSql, id, true);

            saveCustSqlFormRelation(formCustSql);

            return ResultMsg.SUCCESS(id);
        }

        // 更新
        // TODO 如何判断是否有实质更新？
        formCustSql.setUpdateBy(ContextUtil.getCurrentUserId());
        formCustSql.setUpdator(ContextUtil.getCurrentUserName());
        formCustSql.setUpdateTime(new Date());
        formCustSql.setVersion(formCustSql.getVersion() + 1);

        update(formCustSql);

        saveSqlFields(formCustSql, id, false);


        saveCustSqlFormRelation(formCustSql);

        return ResultMsg.SUCCESS(id);
    }

    private void saveCustSqlFormRelation(FormCustSql formCustSql) {
        if (StringUtil.isEmpty(formCustSql.getFormKey())) {
            return;
        }
        FormCustSqlRelation formCustSqlRelation = formCustSql.getCustForm();

        FormCustSqlRelation existsRelation = this.formCustSqlRelationMananger.getByFormKey(formCustSql.getFormKey());
        if (existsRelation != null && existsRelation.getListId().equals(formCustSqlRelation.getId())) {
            FormCustSql formSql = (FormCustSql) get(existsRelation.getId());
            String formSqlName = (formSql == null) ? "未知???" : formSql.getName();
            throw new BusinessMessage("表单[" + formCustSqlRelation.getFormName() + "]已经被自定义列表[" + formSqlName + "] 使用，请重新创建一个新的表单，为当前列表专用！");
        }


        formCustSqlRelation.setListId(formCustSql.getId());

        if (StringUtil.isEmpty(formCustSqlRelation.getId())) {
            this.formCustSqlRelationMananger.create(formCustSqlRelation);
        } else {
            this.formCustSqlRelationMananger.update(formCustSqlRelation);
        }
    }


    private ResultMsg<String> checkParams(FormCustSql formCustSql, String id) {
        DefaultQueryFilter defaultQueryFilter = new DefaultQueryFilter();
        if (StringUtil.isNotEmpty(id)) {
            defaultQueryFilter.addFilter("id_", id, QueryOP.NOT_EQUAL);
        }

        String code = formCustSql.getCode();
        defaultQueryFilter.addFilter("code_", code, QueryOP.EQUAL);
        List<FormCustSql> query = this.formCustSqlDao.query((QueryFilter) defaultQueryFilter);
        if (!query.isEmpty()) {
            return ResultMsg.ERROR("编码已存在,code:" + code);
        }


        String tableName = formCustSql.getTableName();
        if (StringUtil.isEmpty(tableName)) {
            this.logger.error("自定义SQL的主表不存在,code:{}", code);
            return ResultMsg.ERROR("自定义SQL的主表不存在");
        }

        List<FormCustSqlFields> newFieldsList = formCustSql.getFieldsList();


        Map<String, String> fieldNameColumnMap = (Map<String, String>) newFieldsList.stream().filter(fields -> Util.equals(fields.getTableName(), tableName)).collect(Collectors.toMap(FormCustSqlFields::getFieldName, FormCustSqlFields::getName));


        String pkName = formCustSql.getPkName();
        if (StringUtil.isEmpty(fieldNameColumnMap.get(pkName))) {
            this.logger.error("自定义SQL的主键不存在,code:{},tableName:{},pkName:{}", new Object[]{code, tableName, pkName});
            return ResultMsg.ERROR("自定义SQL的主键不存在,tableName:" + tableName + ",pkName:" + pkName);
        }

        List<String> columnList = (List<String>) newFieldsList.stream().map(FormCustSqlFields::getName).collect(Collectors.toList());


        List<SqlButtonVO> buttonList = JSONObjectUtil.toList(formCustSql.getButtons(), SqlButtonVO.class);

        if (CollectionUtils.isEmpty(buttonList)) {
            return ResultMsg.SUCCESS();
        }


        List<SqlButtonVO> uniqueAliasButtonList = (List) buttonList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> {
                    return new TreeSet<SqlButtonVO>(Comparator.comparing(SqlButtonVO::getAlias));
                }), ArrayList::new));

        if (buttonList.size() != uniqueAliasButtonList.size()) {
            this.logger.error("请检查按钮别名是否重复,code:{},tableName:{},pkName:{}", new Object[]{code, tableName, pkName});
            return ResultMsg.ERROR("请检查自定义按钮别名是否重复");
        }

        if (!CollectionUtils.isEmpty(buttonList)) {
            for (SqlButtonVO sqlButtonVO : buttonList) {
                if (Util.equals(sqlButtonVO.getClickType(), Integer.valueOf(1))) {
                    String dataChangeStr = sqlButtonVO.getDataChange();

                    String[] dataChangeArray = dataChangeStr.split(";");

                    for (String dataChange : dataChangeArray) {
                        String[] changeData = dataChange.split("=");
                        String buttonAlias = sqlButtonVO.getAlias();
                        if (changeData.length != 2) {
                            this.logger.error("自定义按钮数值变化配置不正确,code:{},btnAlias:{},dataChange:{}", new Object[]{code, buttonAlias, dataChange});

                            return ResultMsg.ERROR("自定义按钮数值变化配置不正确:" + dataChange);
                        }
                        String fieldName = changeData[0];
                        String value = changeData[1];

                        if (!columnList.contains(fieldName) && !fieldNameColumnMap.containsKey(fieldName)) {
                            this.logger.error("自定义按钮数值变化配置不正确,主表中找不到对应的字段,code:{},btnAlias:{},dataChange:{},column:{}", new Object[]{code, buttonAlias, dataChange, fieldName});

                            return ResultMsg.ERROR("自定义按钮数值变化配置不正确,主表中找不到对应的字段:" + dataChange);
                        }
                        if (StringUtil.isEmpty(value)) {
                            return ResultMsg.ERROR("自定义按钮数值变化配置不正确,数据不能为空:" + dataChange);
                        }
                    }
                }
            }
        }
        return ResultMsg.SUCCESS();
    }


    protected void saveSqlFields(FormCustSql formCustSql, String id) {
        saveSqlFields(formCustSql, id, false);
    }

    protected void saveSqlFields(FormCustSql formCustSql, String id, boolean isNew) {
        List<FormCustSqlFields> fieldsList = formCustSql.getFieldsList();
        Set<String> fieldNameSet = new HashSet<>(); //检查重复字段

        // create/update/delete
        List<FormCustSqlFields> fieldsListCreate = new ArrayList<>();
        List<FormCustSqlFields> fieldsListUpdate = new ArrayList<>();
        List<String> fieldIdsDel = null;
        if (!isNew) {
            List<FormCustSqlFields> oldFieldsList = this.formCustSqlFieldsManager.getListBySqlId(id);
            if (oldFieldsList != null) {
                fieldIdsDel = (List<String>) oldFieldsList.stream().map(BaseModel::getId).collect(Collectors.toList());
            } else {
                fieldIdsDel = Collections.emptyList();
            }
        }
        for (FormCustSqlFields formCustSqlFields : fieldsList) {
            // 增加重复字段的过滤
            String fieldName = formCustSqlFields.getFieldName();
            if (fieldNameSet.contains(fieldName)) {
                continue;
            } else {
                fieldNameSet.add(fieldName);
            }

            // 后端代码表字段类型改为字符串以支持按label筛选
            if (18 == formCustSqlFields.getControlType()) {
                if (!"varchar".equalsIgnoreCase(formCustSqlFields.getDataType())) {
                    formCustSqlFields.setDataType("varchar");
                }
            }
            if (isNew) {
                formCustSqlFields.setId(IdUtil.getSuid());
                formCustSqlFields.setCreateBy(ContextUtil.getCurrentUserId());
                formCustSqlFields.setCreator(ContextUtil.getCurrentUserName());
                formCustSqlFields.setCreateTime(new Date());
                formCustSqlFields.setSqlId(id);
                fieldsListCreate.add(formCustSqlFields);
                continue;
            }

            String fielDid = formCustSqlFields.getId();
            if (fieldIdsDel.contains(fielDid)) {
                //已存在则更新
                fieldIdsDel.remove(fielDid);
                formCustSqlFields.setId(fielDid);
                fieldsListUpdate.add(formCustSqlFields);
                fieldNameSet.add(fieldName);
            } else {
                //不存在创建
                fieldsListCreate.add(formCustSqlFields);
            }
        }
        // 删除未使用的（已排除更新字段）
        this.formCustSqlFieldsManager.removeByIdList(fieldIdsDel);
        // 检查新建列表
        if (CollectionUtil.isNotEmpty(fieldsListCreate)) {
            for (FormCustSqlFields formCustSqlFields : fieldsListCreate) {
                formCustSqlFields.setId(IdUtil.getSuid());
                formCustSqlFields.setCreateBy(ContextUtil.getCurrentUserId());
                formCustSqlFields.setCreator(ContextUtil.getCurrentUserName());
                formCustSqlFields.setCreateTime(new Date());
                formCustSqlFields.setSqlId(id);
                this.formCustSqlFieldsManager.create(formCustSqlFields);
            }
        }
        // 检查更新列表
        if (CollectionUtil.isNotEmpty(fieldsListUpdate)) {
            for (FormCustSqlFields formCustSqlFields : fieldsListUpdate) {
                formCustSqlFields.setSqlId(id);
                formCustSqlFields.setUpdateBy(ContextUtil.getCurrentUserId());
                formCustSqlFields.setUpdator(ContextUtil.getCurrentUserName());
                formCustSqlFields.setUpdateTime(new Date());
                this.formCustSqlFieldsManager.update(formCustSqlFields);
            }
        }
    }


    @Override
    public ResultMsg<List<SqlFieldsVO>> parseSql(FormCustSql formCustSql) {
        String sqlId = formCustSql.getId();
        String sql = formCustSql.getSqlContent();
        String dsKey = formCustSql.getDsKey();

        Map<String, Object> reJson = new HashMap<>();
        sql = this.freemarkerEngine.parseByString(sql, reJson);
        sql = getSql(sql);
        sql = SqlUtil.removeDataSql(sql);

        ResultMsg<String> executeSql = JdbcTemplateUtil.executeSql(dsKey, sql);
        if (!executeSql.getIsOk().booleanValue()) {
            this.logger.error("解析sql异常:{}", executeSql.getMsg());
            return ResultMsg.ERROR(executeSql.getMsg());
        }

        // 解析SQL字段

        ResultMsg<List<SqlFieldsVO>> rsp = getFieldListBySql(dsKey, sql);
        if (!rsp.getIsOk().booleanValue()) {
            return ResultMsg.ERROR(rsp.getMsg());
        }
        List<SqlFieldsVO> fields = (List<SqlFieldsVO>) rsp.getData();

        // TODO 增加流程字段？


        // 检查原来字段配置, 如该字段已存在则沿用之前的配置，包含字段排序
        if (StringUtil.isNotEmpty(sqlId)) {
            List<FormCustSqlFields> fieldsList = this.formCustSqlFieldsManager.getListBySqlId(sqlId);
            if(!CollectionUtils.isEmpty(fieldsList)){
                Map<String, FormCustSqlFields> mFiledsOld = new HashMap<>();
                for (FormCustSqlFields oldFields : fieldsList){
                    mFiledsOld.put(oldFields.getFieldName(), oldFields);
                }
                for (SqlFieldsVO field : fields) {
                    if(mFiledsOld.containsKey(field.getFieldName())){
                        initSqlFiledWithOld(field, mFiledsOld.get(field.getFieldName()));
                    }
                } // end for fields
            }
            Collections.sort(fields, new Comparator<SqlFieldsVO>(){
                @Override
                public int compare(SqlFieldsVO o1, SqlFieldsVO o2) {
                    return o1.getSn()-o2.getSn();
                }
            });
        }
        return rsp;
    }

    private SqlFieldsVO initSqlFiledWithOld(SqlFieldsVO field, FormCustSqlFields oldFields) {
        // 检查字段名
        if (!oldFields.getFieldName().equalsIgnoreCase(field.getFieldName())) {
            return field;
        }


        if (StringUtil.isNotEmpty(oldFields.getFieldDesc())) {
            field.setFieldDesc(oldFields.getFieldDesc());
        }
        if (StringUtil.isNotEmpty(oldFields.getAlign())) {
            field.setAlign(oldFields.getAlign());
        }
        if (StringUtil.isNotEmpty(oldFields.getHidden())) {
            field.setHidden(oldFields.getHidden());
        }
        if (StringUtil.isNotEmpty(oldFields.getUnit())) {
            field.setUnit(oldFields.getUnit());
        }
        if (StringUtil.isNotEmpty(oldFields.getWidth())) {
            field.setWidth(oldFields.getWidth());
        }
        if (StringUtil.isNotEmpty(oldFields.getUnit())) {
            field.setUnit(oldFields.getUnit());
        }
        // 排序字段，强制更新
        if (StringUtil.isNotEmpty(oldFields.getSn())) {
            field.setSn(oldFields.getSn());
        }
        if (StringUtil.isNotEmpty(oldFields.getHref())) {
            field.setHref(oldFields.getHref());
        }
        if (StringUtil.isNotEmpty(oldFields.getControlType())) {
            field.setControlType(oldFields.getControlType());
        }
        if (StringUtil.isNotEmpty(oldFields.getDateFormat())) {
            field.setDateFormat(oldFields.getDateFormat());
        }
        if (StringUtil.isNotEmpty(oldFields.getExpand())) {
            field.setExpand(oldFields.getExpand());
        }
        if (StringUtil.isNotEmpty(oldFields.getAddAble())) {
            field.setAddAble(oldFields.getAddAble());
        }
        if (StringUtil.isNotEmpty(oldFields.getEditAble())) {
            field.setEditAble(oldFields.getEditAble());
        }
        if (StringUtil.isNotEmpty(oldFields.getImportAble())) {
            field.setImportAble(oldFields.getImportAble());
        }
        if (StringUtil.isNotEmpty(oldFields.getExportAble())) {
            field.setExportAble(oldFields.getExportAble());
        }
        if (StringUtil.isNotEmpty(oldFields.getRules())) {
            field.setRules(oldFields.getRules());
        }
        if (StringUtil.isNotEmpty(oldFields.getPlaceholder())) {
            field.setPlaceholder(oldFields.getPlaceholder());
            if (StringUtil.isNotEmpty(oldFields.getFuzz())) {
                field.setFuzz(oldFields.getFuzz());
            }
        }
        return field;
    }


    private ResultMsg<List<SqlFieldsVO>> getFieldListBySql(String dsKey, String sql) {
        TableOperUtil tableOperUtil = new TableOperUtil();
        ResultMsg<List<SqlFieldsVO>> fieldListRsp = tableOperUtil.getColumnModalBySql(sql, dsKey);
        if (!fieldListRsp.getIsOk().booleanValue()) {
            return ResultMsg.ERROR(fieldListRsp.getMsg());
        }

        List<SqlFieldsVO> fieldList = (List<SqlFieldsVO>) fieldListRsp.getData();

        JSONObject columnTableRef = null;
        try {
            columnTableRef = SqlUtil.getColumnTableRefJo(sql);
        } catch (JSQLParserException e) {
            return ResultMsg.ERROR(ExceptionUtil.getExceptionMessage((Throwable) e));
        }

        JSONObject defaultTable = columnTableRef.getJSONObject("default");

        String tableAlias = "";
        if (defaultTable != null) {
            tableAlias = defaultTable.getString("tableAlias");
        }


        for (SqlFieldsVO sqlFieldVO : fieldList) {
            String column = sqlFieldVO.getFieldName().toLowerCase() + "." + sqlFieldVO.getName().toLowerCase();
            if (!columnTableRef.containsKey(column) && StringUtil.isEmpty(sqlFieldVO.getTableAlias())) {
                sqlFieldVO.setTableAlias(tableAlias);

                continue;
            }
            JSONObject jo = (JSONObject) columnTableRef.get(column);

            sqlFieldVO.setTableAlias(jo.getString("tableAlias"));
            if (jo.containsKey("tableName")) {
                sqlFieldVO.setTableName(jo.getString("tableName"));
            }
        }
        return ResultMsg.SUCCESS(fieldList);
    }


    private String getSql(String sql) {
        String regex = "\\$\\{\\w+\\}";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(sql);
        while (m.find()) {
            String whereParam = m.group();

            sql = sql.replace(whereParam, "'' or 1=1 or 1=''");
            sql = sql.replace("'''", "''");
        }


        regex = "\\{\\w+\\}";
        p = Pattern.compile(regex);
        m = p.matcher(sql);
        while (m.find()) {
            String whereParam = m.group();

            sql = sql.replace(whereParam, " 1=1 ");
        }

        return sql;
    }


    public FormCustSql getByCode(String code, boolean getFields) {
        DefaultQueryFilter defaultQueryFilter = new DefaultQueryFilter();
        defaultQueryFilter.addFilter("code_", code, QueryOP.EQUAL);
        List<FormCustSql> query = this.formCustSqlDao.query((QueryFilter) defaultQueryFilter);
        if (query.isEmpty()) {
            return null;
        }
        FormCustSql sql = query.get(0);

        // fields/buttons/conditions

        if (getFields) {
            List<FormCustSqlFields> fieldsList = this.formCustSqlFieldsManager.getListBySqlId(sql.getId());
            sql.setFieldsList(fieldsList);

            List<FormCustSql.FieldGroup> groupsList = createGroupList(fieldsList);
            if (!groupsList.isEmpty()) {
                sql.setGroupsList(groupsList);
            }
        }
        return sql;
    }

    private List<FormCustSql.FieldGroup> createGroupList(List<FormCustSqlFields> fieldsList) {
        List<FormCustSql.FieldGroup> groupsList = new ArrayList<>();
        String groupPre = null;
        String groupCur = null;
        Integer countGroup = 0;
        for (FormCustSqlFields field : fieldsList) {
            if (1 == field.getHidden()) {
                continue;
            }
            groupCur = field.getFieldGroup();
            if (groupCur == null) {
                groupCur = "";
            }
            if (groupCur.equalsIgnoreCase(groupPre)) {
                countGroup++;
            } else {
                if (groupPre != null) {
                    groupsList.add(new FormCustSql.FieldGroup(groupPre, countGroup));
                }
                groupPre = groupCur;
                countGroup = 1;
            }
        }
        if (groupPre != null) {
            groupsList.add(new FormCustSql.FieldGroup(groupPre, countGroup));
        }
        return groupsList;
    }


    public ResultMsg<JSONObject> export(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));

        DefaultQueryFilter defaultQueryFilter = new DefaultQueryFilter();
        defaultQueryFilter.addFilter("id_", idList, QueryOP.IN);
        List<FormCustSql> sqlList = this.formCustSqlDao.query((QueryFilter) defaultQueryFilter);

        JSONArray listJson = new JSONArray();
        for (FormCustSql formCustSql : sqlList) {
            List<FormCustSqlFields> fieldsList = this.formCustSqlFieldsManager.getListBySqlId(formCustSql.getId());
            formCustSql.setFieldsList(fieldsList);

            FormCustSqlRelation custForm = this.formCustSqlRelationMananger.getByFormKey(formCustSql.getFormKey());
            formCustSql.setCustForm(custForm);

            listJson.add(toJson(formCustSql));
        }

        JSONObject exportData = new JSONObject();
        exportData.put("sqls", listJson);
        //exportData.put("sqls", JSON.toJSONString(sqlList));
        exportData.put("fileName", ((FormCustSql) sqlList.get(0)).getName());

        return ResultMsg.SUCCESS(exportData);
    }


    public ResultMsg<String> importJson(String json) {
        List<FormCustSql> sqlList = JSONObjectUtil.toList(json, FormCustSql.class);

        ResultMsg<String> returnRspMsg = ResultMsg.SUCCESS("导入成功");

        for (FormCustSql formCustSql : sqlList) {
            formCustSql.setId(null);
            ResultMsg<String> saveRsp = save(formCustSql);

            if (!saveRsp.getIsOk().booleanValue()) {
                returnRspMsg = saveRsp;
            }
        }

        return returnRspMsg;
    }


    public void removeCustSqlByIds(String[] aryIds) {
        removeByIds(aryIds);

        for (String id : aryIds) {
            List<FormCustSqlFields> fieldsList = this.formCustSqlFieldsManager.getListBySqlId(id);
            List<String> fieldsIdList = (List<String>) fieldsList.stream().map(BaseModel::getId).collect(Collectors.toList());
            this.formCustSqlFieldsManager.removeByIdList(fieldsIdList);
            this.formCustSqlRelationMananger.removeByListId(id);
        }
    }

    @Override
    public JSONObject toJson(FormCustSql formCustSql) {
        JSONObject json = new JSONObject();
        BeanUtil.copyProperties(formCustSql, json);
        //特别处理
        // 按钮buttons
        if(json.getString("buttons")!=null){
            json.put("buttons", JSONArray.parseArray(json.getString("buttons")));
            json.remove("buttonList");
        }
        // 条件conditions
        if(json.getString("conditions")!=null){
            json.put("conditions", JSONArray.parseArray(json.getString("conditions")));
        }

        // 扩展expand
        if(json.getString("expand")!=null){
            json.put("expand", JSONObject.parseObject(json.getString("expand")));
        }
        // sqlTableList
        if(json.getString("sqlTableList")!=null){
            json.put("sqlTableList", JSONArray.parseArray(json.getString("sqlTableList")));
        }
        // fieldsList, 解析expand参数
        JSONArray fieldsList =  json.getJSONArray("fieldsList");
        if(fieldsList!=null){
            for(int i=0; i<fieldsList.size(); i++){
                JSONObject fieldJson = fieldsList.getJSONObject(i);
                if(fieldJson.getString("expand")!=null){
                    fieldJson.put("expand", JSONObject.parseObject(fieldJson.getString("expand")));
                    fieldsList.set(i, fieldJson);
                }
            }
        }
        return json;
    }

    /**
     * 检查module（若无则从group获取module值）
     * @param formCustSql
     */
    public void checkModuleInFormCustSql(FormCustSql formCustSql){
        JSONObject expandJo = JSONObjectUtil.parseExpand(formCustSql.getExpand());
        String busModule = "obpm";
        if(expandJo.containsKey("busModule")){
            busModule =expandJo.getString("busModule");
        }
        if(StringUtil.isNotEmpty(formCustSql.getGroupId())){
            SysTreeNode treeNode = sysTreeNodeDao.get(formCustSql.getGroupId());
            if(treeNode!=null){
                // 本级
                if(StringUtil.isNotEmpty(treeNode.getBusModule())){
                    busModule = treeNode.getBusModule();
                    // 查找上一级
                }else if(StringUtil.isNotEmpty(treeNode.getParentId())){
                    String parentId = treeNode.getParentId();
                    treeNode = sysTreeNodeDao.get(parentId);
                    if(treeNode!=null && StringUtil.isNotEmpty(treeNode.getBusModule())){
                        busModule = treeNode.getBusModule();
                    }
                }
            }
        }
        expandJo.put("busModule", busModule);
        formCustSql.setExpand(JSONObjectUtil.toJsonStr(expandJo));
    }
}
